package com.zx.zxapibackend.security.config;

import com.zx.zxapibackend.security.common.UserDetailsServiceImpl;
import com.zx.zxapibackend.security.exception.SimpleAccessDeniedHandler;
import com.zx.zxapibackend.security.exception.SimpleAuthenticationEntryPoint;
import com.zx.zxapicommon.constant.CookieConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;


/**
 * 自定义SpringSecurity配置类
 *
 * @author 张旭
 * @version 1.0
 */
@Configuration
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    private String[] pathPatterns = {"/user/oauth2/**", "/user/register", "/user/login", "/user/loginBySms", "/v3/api-docs", "/user/logoutSuccess", "/user/getpassusertype", "/user/sendPassUserCode", "/user/authPassUserCode", "/user/updateUserPass"};

    private String[] adminPath = {"/user/list/page",
            "/user/list",
            "/userInterfaceInfo/add",
            "/userInterfaceInfo/delete",
            "/userInterfaceInfo/update",
            "/userInterfaceInfo/get",
            "/userInterfaceInfo/list",
            "/userInterfaceInfo/list/page",
            "/interfaceInfo/list",
            "/interfaceInfo/list/AllPage",
            "/interfaceInfo/online",
            "/interfaceInfo/online",};

    @Autowired
    private SimpleAuthenticationEntryPoint simpleAuthenticationEntryPoint;

    @Autowired
    private SimpleAccessDeniedHandler simpleAccessDeniedHandler;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;


    /**
     * 配置PasswordEncoder
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 覆盖默认的AuthenticationManager
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    /**
     * 从工厂中暴露出来
     *
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    /**
     * 配置跨域相关
     *
     * @return
     */
/*
    @Bean
    public CorsConfigurationSource configurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }
*/


    /**
     * 自定义Filter，覆盖fromLogin()中的Filter
     *
     * @return
     * @throws Exception
     */
   /* @Bean
    public LoginFilter loginFilter() throws Exception {
        LoginFilter loginFilter = new LoginFilter();
        loginFilter.setFilterProcessesUrl("/user/login");//指定认证url
        loginFilter.setUsernameParameter("userAccount");//指定接收json用户名key
        loginFilter.setPasswordParameter("userPassword");//指定接收json密码key
        loginFilter.setAuthenticationManager(authenticationManagerBean());
        //认证成功处理
        loginFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                Map<String, Object> result = new HashMap<String, Object>();
                result.put("code", "0");//打印登录成功信息
                //result.put("status", 200);//打印状态码   此处改为setStatus
                result.put("data", authentication.getPrincipal());//获得身份信息
                //result.put("authentication", authentication);//打印认证信息
                response.setContentType("application/json;charset=UTF-8");//设置响应类型
                response.setStatus(HttpStatus.OK.value());//设置登录成功之后的状态
                String s = new ObjectMapper().writeValueAsString(result);//json格式转字符串
                response.getWriter().println(s);//打印json格式数据
            }
        });
        //认证失败处理
        loginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("msg", "登录失败：" + exception.getMessage());
            //result.put("status", 500);//打印状态码   此处改为setStatus
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());//设置登录失败之后的状态
            log.error("登录失败：{}",exception.getMessage());
            String s = new ObjectMapper().writeValueAsString(result);
            response.getWriter().println(s);
        });
        return loginFilter;

    }

*/

    /**
     * http相关
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();

        //配置鉴权相关
        http.authorizeRequests()
                .antMatchers(pathPatterns).permitAll()//经过测试，这里配置/user/login成功放行
                .antMatchers(adminPath).hasRole("admin")
                //.anyRequest().authenticated()
                .anyRequest().permitAll()
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(simpleAuthenticationEntryPoint)
                .accessDeniedHandler(simpleAccessDeniedHandler);


        //配置登出相关
        http.logout()
                .logoutUrl("/user/logout") //指定用户注销登录时请求访问的地址
                .deleteCookies(CookieConstant.headAuthorization)//指定用户注销登录后删除的 Cookie。
                .deleteCookies(CookieConstant.autoLoginAuthCheck)
                .logoutSuccessUrl("http://117.72.8.188/api/user/logoutSuccess");//指定退出登录后跳转的地址

       // http.cors().configurationSource(configurationSource());

        //开启会话管理，每个浏览器最多只能一个用户登录
        http.sessionManagement()
                .maximumSessions(1)
                .maxSessionsPreventsLogin(true);

        //使用自定义登录loginfilter，需要配置http.fromlogin();
        //  http.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);
    }


}
